package Stock;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.io.*;

public class Wallet {
	private String m_Name;
	private List<Stock> m_Stocks;
	private List<Integer> m_Percentages;
	private List<Float> m_ATR;
	private Float m_ATRBaseline;
	private boolean m_Trading;
	private float m_StartValue;
	
	private SortedMap<Date, Transaction> m_TotalList;
	
	
	//staticgraph is de map waarin bijgehouden wordt tussen welke tijdspannes de grafiek statis wordt
	private SortedMap<Date, PaperValue> m_StaticGraph;
	//de waarden die de grafiek op de voorgrond maakt
	private List<Transaction> m_ProfitGraph;

	public Wallet(String name) {
		m_Name = name;
		m_Stocks = new ArrayList<Stock>();
		m_Percentages = new ArrayList<Integer>();
		System.out.println("walet name:" + m_Name);
		
		m_Trading=true;
		m_StaticGraph=new TreeMap<Date, PaperValue>();
		m_ProfitGraph=new ArrayList<Transaction>();
		
		m_StartValue=0;
	}
	
	public SortedMap<Date, PaperValue> getStaticGraph(){
		return m_StaticGraph;
	}

	public List<Transaction> getProfitGraph()
	{
		return m_ProfitGraph;
	}
	
	public List<Stock> getStockValues() {
		return m_Stocks;
	}
	
	public float getStartvalue(){
		return m_StartValue;
	}
	
	public List<Transaction> GetTotalStock()
	{
		List<Transaction> totals=new ArrayList<Transaction>(m_TotalList.values());
		return totals;
	}

	public Map<Date, Transaction> getTotal()
	{
		calculateTotal();
		return m_TotalList;
	}
	
	public List<Float> getATR(List<Transaction> list) {
		return m_ATR;
	}

	public void setBaseline(float baselineValue)
	{
		m_ATRBaseline=baselineValue;
	}
	
	public float getBaseline()
	{
		return m_ATRBaseline;
	}
	
	public boolean getTrading()
	{
		return m_Trading;
	}
	
	public void checkATR()
	{
		
		if(m_ATR.get(m_ATR.size()-1)>=m_ATRBaseline)
		{
			m_Trading=false;
			
			//als de trading op false komt staan wordt de laaste waarde in de total list genomen (dit zou moeten de waarde zijn waarop de ATR te hoog wordt)
			//de begindatum en adjustedclose waarde worden opgeslaan in de map
			Transaction Line=m_TotalList.get(m_TotalList.lastKey());
			
			PaperValue newValue=new PaperValue(Line.getStockDate(), Line.getAdjustmentClose());
			m_StaticGraph.put(Line.getStockDate(), newValue);
		}
		else
		{
			//wanneer we overschakelen van non trading naar trading wordt de eind datum opgeslaan
			if(!m_StaticGraph.isEmpty() && !m_Trading)
			{
				m_StaticGraph.get(m_StaticGraph.lastKey()).setEndDate(m_TotalList.lastKey());
			}
			
			m_Trading=true;
		}
	}
	
	public void addStock(Stock newstock) throws Exception {
		m_Stocks.add(newstock);

		for (Stock stock : m_Stocks) {
			int Percentage = 10;
		 
			if (Percentage > 0) 
			{
				m_Percentages.add(Percentage);
			} 
			else 
			{
				throw new Exception("not a valid Percentage");
			}
		}
		
		m_StartValue+=newstock.getStartValue();
	}

	public void removeStock(Stock delete) {
		int position = m_Stocks.indexOf(delete);

		m_Stocks.remove(position);
		m_Percentages.remove(position);
	}

	public float calculateProfit() {
		float profit = 0;

		for (Stock stock : m_Stocks) {
			profit += stock.getCurrentValue() - stock.getStartValue();
		}

		return profit;
	}
	
	private Transaction transactionPercentage(Transaction value)
	{
		Transaction ReturnTran=new Transaction(calcPercentage(value.getOpen()), calcPercentage(value.getHigh())
				, calcPercentage(value.getLow()), calcPercentage(value.getClose()), calcPercentage(value.getAdjustmentClose()), value.getStockDate());
		
		return ReturnTran;
	}
	
	private float calcPercentage(float value)
	{
		value=(value/m_StartValue)*100;
		
		return value;
	}
	
	public void calculateTotal()
	{
		m_TotalList=new TreeMap<Date, Transaction>();
		
		for (Stock stock : m_Stocks) 
		{
			List<Transaction> translist=stock.getStockTransactions();
			for(Transaction trans : translist)
			{
				Date syncDate = trans.getStockDate();
				
				Transaction TransTotal=m_TotalList.get(syncDate);
				
				if(TransTotal!=null)
				{
					float open=TransTotal.getOpen()+trans.getOpen();
					float high=TransTotal.getClose()+trans.getClose();
					float low=TransTotal.getLow()+trans.getLow();
					float close=TransTotal.getClose()+trans.getClose();
					float adjustmentClose=TransTotal.getAdjustmentClose()+trans.getAdjustmentClose();
					
					
					TransTotal.SetValues(open, high, low, close, adjustmentClose);
					
					m_TotalList.put(syncDate, TransTotal);
				}
				else
				{
					m_TotalList.put(syncDate, trans);
				}
			}
		}
		
		//functie begon te groot te worden dus in 2 gesplitst
		totalInPercentage();		
	}
	
	private void totalInPercentage()
	{
		boolean staticgraph=false;
		PaperValue Control=null;
		int counter=0;
		float raisedvalue=0;
		
		for(Transaction trans : m_TotalList.values())
		{
			trans=transactionPercentage(trans);
			
			//als de datum een startdatum is van een statische zone wordt staticgraph op true gezet
			staticgraph=m_StaticGraph.containsKey(trans.getStockDate());
			
			if(staticgraph)
			{
				//in de eerste passthrough is counter 0 dan wordt control ingesteld en de raisedvalue
				if(counter==0)
				{
					Control=m_StaticGraph.get(trans.getStockDate());
					raisedvalue=Control.getValue();
				}
				
				//de profitvalues worden berekend en er wordt gekeken of we aan het eind zitten van de statische zone
				staticgraph=calculateTotalProfit(Control, trans);
				
				counter++;
			}
			else
			{
				counter=0;
			
				//als we niet in een statische zone zitten worden de waarden verhoogt met raisedvalue en in profitgraph gestoken
				Transaction profittrans = trans;
				profittrans.SetValues(trans.getOpen()+raisedvalue, trans.getHigh()+raisedvalue, trans.getLow()+raisedvalue, 
							trans.getClose()+raisedvalue, trans.getAdjustmentClose()+raisedvalue);
				
				m_ProfitGraph.add(profittrans);
			}
			
			m_TotalList.put(trans.getStockDate(), trans);
		}
	}
	
	private boolean calculateTotalProfit(PaperValue Control, Transaction trans)
	{
		//als de datum voor de eind datum valt worden alle waardes statisch gehouden op die van control
		//en wordt false gereturned om aan te tonen dat we nog altijd in de statische zone zitten
		if(trans.getStockDate().before(Control.getEndDate()))
		{
			trans.SetValues(Control.getValue(), Control.getValue(),Control.getValue(), Control.getValue(), Control.getValue());
			m_ProfitGraph.add(trans);
			return false;
		}

		//indien de datum gelijk is aan de eind datum worden de waarden verhoogd met de profitvalue
		//er wordt true gereturned om aan te tonen dat de statische zone voorbij is
		trans.SetValues(trans.getOpen()+Control.getValue(), trans.getHigh()+Control.getValue(), 
					trans.getLow()+Control.getValue(), trans.getClose()+Control.getValue(), trans.getAdjustmentClose()+Control.getValue());
		m_ProfitGraph.add(trans);
		return true;
	}

	public void loadWallet(String RealPath) {
		String FilePath = RealPath + "Wallets/" + m_Name + ".txt";

		System.out.println(FilePath);
		try {
			System.out.println("create file");
			File file = new File(FilePath);
			System.out.println("File reader");
			FileReader input = new FileReader(file);
			// FileReader input= new FileReader(FilePath);
			System.out.println("bufferedReader");
			BufferedReader reader = new BufferedReader(input);

			System.out.println("reader readline");
			readStock(reader, RealPath);
			
			getTotal();
			input.close();
 
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void readStock(BufferedReader reader, String path)
			throws IOException {
		String line;
		m_Name = reader.readLine();

		m_Stocks.clear();
		m_Percentages.clear();

		while ((line = reader.readLine()) != null) {
 
			int seperator = line.indexOf(";");
			String stockname = line.substring(0, seperator);
			line = line.substring(seperator + 1, line.length());

			seperator = line.indexOf(";");
			int stockPercentage = Integer
					.parseInt(line.substring(0, seperator));
			line = line.substring(seperator + 1, line.length());

			seperator = line.indexOf(";");
			String stockpath = path + "Stock\\" + stockname + ".txt";

			System.out.println(stockpath);

			Stock stock = new Stock(stockname, stockpath);
			m_Stocks.add(stock);
			m_Percentages.add(stockPercentage);
			m_StartValue+=stock.getStartValue();
		}

	}

	public void SaveWallet() {
		try {
			// TODO controleren of dit bestand al bestaat
			FileWriter writer = new FileWriter("./Wallets/" + m_Name + ".txt");
			String output = m_Name + "\n";

			for (Stock stock : m_Stocks) {
				output += stock.getStockName() + ";";

				int percentage = m_Percentages.get(m_Stocks.indexOf(stock));
				output += percentage + ";";

				output += "./Stocks/" + stock.getStockName() + ".txt";
				output += "\n";
			}

			writer.write(output);
			writer.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public Stock getStock(int index) {
		return m_Stocks.get(index);
	}
}
